package com.ruoyi.ring.service.impl;

import cn.hutool.core.convert.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.Builder;
import com.ruoyi.ring.domain.UserPhysiology;
import com.ruoyi.ring.domain.UserPhysiologySet;
import com.ruoyi.ring.domain.dto.PhysiologyInfoQueryDTO;
import com.ruoyi.ring.domain.dto.PhysiologyTaskQueryDTO;
import com.ruoyi.ring.domain.vo.UserPhysiologyVO;
import com.ruoyi.ring.mapper.UserPhysiologyMapper;
import com.ruoyi.ring.mapper.UserPhysiologySetMapper;
import com.ruoyi.ring.service.IUserPhysiologyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 生理期信息Service业务层处理
 * 
 * @author liuwp
 * @date 2025-09-30
 */
@Slf4j
@Service
public class UserPhysiologyServiceImpl implements IUserPhysiologyService 
{
    @Resource
    private UserPhysiologyMapper userPhysiologyMapper;
    @Resource
    private UserPhysiologySetMapper userPhysiologySetMapper;

    /**
     * 查询生理期信息
     * 
     * @param id 生理期信息主键
     * @return 生理期信息
     */
    @Override
    public UserPhysiology selectUserPhysiologyById(Long id)
    {
        return userPhysiologyMapper.selectUserPhysiologyById(id);
    }

    /**
     * 查询生理期信息列表
     * 
     * @param userPhysiology 生理期信息
     * @return 生理期信息
     */
    @Override
    public List<UserPhysiology> selectUserPhysiologyList(UserPhysiology userPhysiology)
    {
        return userPhysiologyMapper.selectUserPhysiologyList(userPhysiology);
    }

    /**
     * 根据业务主键查询一条记录：生理期信息
     *
     * @param userPhysiology 生理期信息
     * @return 生理期信息
     */
    @Override
    public UserPhysiology selectOneUserPhysiology(UserPhysiology userPhysiology)
    {
        return userPhysiologyMapper.selectOneUserPhysiology(userPhysiology);
    }

    /**
     * 新增生理期信息
     * 
     * @param userPhysiology 生理期信息
     * @return 结果
     */
    @Override
    public int insertUserPhysiology(UserPhysiology userPhysiology)
    {
        userPhysiology.setCreateTime(DateUtils.getNowDate());
        return userPhysiologyMapper.insertUserPhysiology(userPhysiology);
    }

    /**
     * 修改生理期信息
     * 
     * @param userPhysiology 生理期信息
     * @return 结果
     */
    @Override
    public int updateUserPhysiology(UserPhysiology userPhysiology)
    {
        userPhysiology.setUpdateTime(DateUtils.getNowDate());
        return userPhysiologyMapper.updateUserPhysiology(userPhysiology);
    }

    @Override
    public int updateUserPhysiologyCondition(UserPhysiology userPhysiology, UserPhysiology userPhysiologyCondition)
    {
                userPhysiology.setUpdateTime(DateUtils.getNowDate());
        return userPhysiologyMapper.updateUserPhysiologyCondition(userPhysiology, userPhysiologyCondition);
    }

    /**
     * 批量删除生理期信息
     * 
     * @param ids 需要删除的生理期信息主键
     * @return 结果
     */
    @Override
    public int deleteUserPhysiologyByIds(Long[] ids)
    {
        return userPhysiologyMapper.deleteUserPhysiologyByIds(ids);
    }

    /**
     * 删除生理期信息信息
     * 
     * @param id 生理期信息主键
     * @return 结果
     */
    @Override
    public int deleteUserPhysiologyById(Long id)
    {
        return userPhysiologyMapper.deleteUserPhysiologyById(id);
    }

    /**
     * 条件删除生理期信息
     *
     * @param userPhysiology 生理期信息
     * @return 结果
     */
    @Override
    public int deleteUserPhysiologyByCondition(UserPhysiology userPhysiology)
    {
        return userPhysiologyMapper.deleteUserPhysiologyByCondition(userPhysiology);
    }

    @Override
    public UserPhysiologyVO queryPhysiologyInfo(PhysiologyInfoQueryDTO queryDTO) {
        long userId = queryDTO.getUserId();
        UserPhysiologyVO userPhysiologyVO = new UserPhysiologyVO();
        //生理周期设置
        UserPhysiologySet physiologySet = userPhysiologySetMapper.selectOneUserPhysiologySet(Builder.of(UserPhysiologySet::new).with(UserPhysiologySet::setUserId, userId).build());
        //周期信息
        UserPhysiology userPhysiology = userPhysiologyMapper.queryOnePhysiologyInfo(queryDTO);
        if(physiologySet != null){
            if (!DateUtils.isAfterAndDifferentMonth(queryDTO.getSelectDate(),new Date()) && userPhysiology == null){
                return new UserPhysiologyVO();
            }
            if(userPhysiology != null){
                userPhysiologyVO = Convert.convert(UserPhysiologyVO.class,userPhysiology);
            }else {
                long menstrualPeriodDays = physiologySet.getMenstrualPeriodDays(); // 生理期天数;
                long periodDays = physiologySet.getPeriodDays(); // 周期间隔天数
                Date startDate = queryDTO.getUpdStartDate() != null ? queryDTO.getUpdStartDate() : physiologySet.getStartDate(); // 上次生理期开始日期
                Date selectDate = queryDTO.getSelectDate();// 选择的时间
                userPhysiologyVO = processMonth(startDate, selectDate, Convert.toInt(menstrualPeriodDays), Convert.toInt(periodDays));
            }
        }
        return userPhysiologyVO;
    }
    @Override
    public UserPhysiologyVO queryPhysiologyTaskInfo(PhysiologyTaskQueryDTO taskQueryDTO) {
        return processMonth(taskQueryDTO.getStartDate(), taskQueryDTO.getSelectDate(), Convert.toInt(taskQueryDTO.getMenstrualPeriodDays()), Convert.toInt(taskQueryDTO.getPeriodDays()));
    }

    @Override
    public UserPhysiology queryOneUserPhysiology() {
        return userPhysiologyMapper.queryOnePhysiologyInfo(Builder.of(PhysiologyInfoQueryDTO::new).
                with(PhysiologyInfoQueryDTO::setUserId, SecurityUtils.getUserId()).
                with(PhysiologyInfoQueryDTO::setSelectDate, new Date()).build());
    }

    @Override
    public UserPhysiology queryOnePhysiologyInfo(PhysiologyInfoQueryDTO queryDTO) {
        return userPhysiologyMapper.queryOnePhysiologyInfo(Builder.of(PhysiologyInfoQueryDTO::new).
                with(PhysiologyInfoQueryDTO::setUserId, queryDTO.getUserId()).
                with(PhysiologyInfoQueryDTO::setSelectDate, queryDTO.getSelectDate()).build());
    }


    /**
     * 处理后续月份的生理周期数据
     * @param startDate 生理期开始日期
     * @param selectDate 目标月份日期
     * @param menstrualPeriodDays 生理期天数
     * @param periodDays 周期间隔天数
     * @return 后续月份生理周期数据VO
     */
//    private UserPhysiologyVO processMonth(Date startDate, Date selectDate, Integer menstrualPeriodDays, Integer periodDays) {
//        Calendar targetCal = Calendar.getInstance();
//        targetCal.setTime(selectDate);
//        int targetYear = targetCal.get(Calendar.YEAR);
//        int targetMonth = targetCal.get(Calendar.MONTH) + 1;
//        List<Date> dateList = getCyclesInMonth(startDate,periodDays,targetYear,targetMonth);
//        Date periodStartDate;
//        if(dateList.size() > 0){
//            periodStartDate = dateList.get(dateList.size() -1);
//        }else {
//            periodStartDate = startDate;
//        }
//        UserPhysiologyVO vo = new UserPhysiologyVO();
//        // 计算目标月份内的生理期日期
////        int monthOffset = DateUtils.queryMonthsDifference(startDate,selectDate);
////        Date periodStartDate = DateUtils.queryMonthOfYear(startDate,monthOffset*periodDays);
////        log.info("初始: " + DateUtils.dateTime(periodStartDate));
//        Date periodEndDate = predictNextPeriodEnd(periodStartDate, menstrualPeriodDays);
//        Date ovulationDayDate = predictOvulationDay(periodStartDate);
//        Date predictFertileStart = predictFertileStart(ovulationDayDate);
//        Date predictFertileEnd = predictFertileEnd(ovulationDayDate);
//        Date nextPeriodStartDate = predictNextPeriodStart(periodStartDate, periodDays);
//        Date nextPeriodEndDate = predictNextPeriodEnd(nextPeriodStartDate, menstrualPeriodDays);
//        // --- 输出结果 ---
////        log.info("月经期开始日: " + DateUtils.dateTime(periodStartDate));
////        log.info("月经期结束日: " + DateUtils.dateTime(periodEndDate));
////        log.info("预测排卵日: " + DateUtils.dateTime(ovulationDayDate));
////        log.info("预测排期开始: " + DateUtils.dateTime(predictFertileStart));
////        log.info("预测排期结束: " + DateUtils.dateTime(predictFertileEnd));
////        log.info("下次月经期开始日: " + DateUtils.dateTime(nextPeriodStartDate));
////        log.info("下次月经期结束日: " + DateUtils.dateTime(nextPeriodEndDate));
//
//        // 生理期（记录日用逗号隔开）
//        List<String> mpDays = DateUtils.getDayStringsBetweenDates(periodStartDate,periodEndDate);
//        String menstrualPeriod = mpDays.stream().collect(Collectors.joining(","));
//
//        // 排卵日 */
//        String ovulationDay = Convert.toStr(DateUtils.queryDayOfMonth(ovulationDayDate));
//
//        // 排卵期（记录日用逗号隔开）
//        List<String> opDays = DateUtils.getDayStringsBetweenDates(predictFertileStart,predictFertileEnd);
//        String ovulationPeriod = opDays.stream().collect(Collectors.joining(","));
//
//        // 预测生理期（记录日用逗号隔开）
//        List<String> days = DateUtils.getDayStringsBetweenDates(nextPeriodStartDate,nextPeriodEndDate);
//        String predictMenstrualPeriod = days.stream().collect(Collectors.joining(","));
//
//        // 更新本月生理期开始日期
//        Date updStartDate = periodStartDate;
//
//        // 更新本月生理期结束日期
//        Date updEndDate = periodEndDate;
//
//        vo.setMenstrualPeriod(menstrualPeriod);
//        vo.setOvulationDay(ovulationDay);
//        vo.setOvulationPeriod(ovulationPeriod);
//        vo.setPredictMenstrualPeriod(predictMenstrualPeriod);
//        vo.setUpdStartDate(updStartDate);
//        vo.setUpdEndDate(updEndDate);
//        return vo;
//    }

    /**
     * 处理后续月份的生理周期数据
     * @param startDate 生理期开始日期
     * @param selectDate 目标月份日期
     * @param menstrualPeriodDays 生理期天数
     * @param periodDays 周期间隔天数
     * @return 后续月份生理周期数据VO
     */
    private UserPhysiologyVO processMonth(Date startDate, Date selectDate, Integer menstrualPeriodDays, Integer periodDays) {
        Calendar targetCal = Calendar.getInstance();
        targetCal.setTime(selectDate);
        int targetYear = targetCal.get(Calendar.YEAR);
        int targetMonth = targetCal.get(Calendar.MONTH) + 1;
        List<Date> dateList = getCyclesInMonth(startDate,periodDays,targetYear,targetMonth);
        Date periodStartDate;
        if(dateList.size() > 0){
            periodStartDate = dateList.get(dateList.size() -1);
        }else {
            periodStartDate = startDate;
        }
        UserPhysiologyVO vo = new UserPhysiologyVO();
        // 计算目标月份内的生理期日期
//        int monthOffset = DateUtils.queryMonthsDifference(startDate,selectDate);
//        Date periodStartDate = DateUtils.queryMonthOfYear(startDate,monthOffset*periodDays);
//        log.info("初始: " + DateUtils.dateTime(periodStartDate));
        Date periodEndDate = predictNextPeriodEnd(periodStartDate, menstrualPeriodDays);
        Date ovulationDayDate = predictOvulationDay(periodStartDate);
        Date predictFertileStart = predictFertileStart(ovulationDayDate);
        Date predictFertileEnd = predictFertileEnd(ovulationDayDate);
        Date nextPeriodStartDate = predictNextPeriodStart(periodStartDate, periodDays);
        Date nextPeriodEndDate = predictNextPeriodEnd(nextPeriodStartDate, menstrualPeriodDays);
        // --- 输出结果 ---
//        log.info("月经期开始日: " + DateUtils.dateTime(periodStartDate));
//        log.info("月经期结束日: " + DateUtils.dateTime(periodEndDate));
//        log.info("预测排卵日: " + DateUtils.dateTime(ovulationDayDate));
//        log.info("预测排期开始: " + DateUtils.dateTime(predictFertileStart));
//        log.info("预测排期结束: " + DateUtils.dateTime(predictFertileEnd));
//        log.info("下次月经期开始日: " + DateUtils.dateTime(nextPeriodStartDate));
//        log.info("下次月经期结束日: " + DateUtils.dateTime(nextPeriodEndDate));

        // 生理期（记录日用逗号隔开）
        List<String> mpDays = DateUtils.getDayStringsBetweenDate(periodStartDate,periodEndDate);
        String menstrualPeriod = mpDays.stream().collect(Collectors.joining(","));

        // 排卵日 */
        String ovulationDay = DateUtils.dateTime(ovulationDayDate);

        // 排卵期（记录日用逗号隔开）
        List<String> opDays = DateUtils.getDayStringsBetweenDate(predictFertileStart,predictFertileEnd);
        String ovulationPeriod = opDays.stream().collect(Collectors.joining(","));

        // 预测生理期（记录日用逗号隔开）
        List<String> days = DateUtils.getDayStringsBetweenDate(nextPeriodStartDate,nextPeriodEndDate);
        String predictMenstrualPeriod = days.stream().collect(Collectors.joining(","));

        // 更新本月生理期开始日期
        Date updStartDate = periodStartDate;

        // 更新本月生理期结束日期
        Date updEndDate = periodEndDate;

        vo.setMenstrualPeriod(menstrualPeriod);
        vo.setOvulationDay(ovulationDay);
        vo.setOvulationPeriod(ovulationPeriod);
        vo.setPredictMenstrualPeriod(predictMenstrualPeriod);
        vo.setUpdStartDate(updStartDate);
        vo.setUpdEndDate(updEndDate);
        return vo;
    }

    /**
     * 计算指定月份内的生理期日期
     * @param startDate 上次生理期开始日期
     * @param selectDate 目标月份日期
     * @param menstrualPeriodDays 生理期天数
     * @param periodDays 周期间隔天数
     * @return 生理期日期列表
     */
    private static List<Date> calculateDatesInMonth(Date startDate, Date selectDate, long menstrualPeriodDays, long periodDays) {
        List<Date> dates = new ArrayList<>();
        Calendar lastStartCal = Calendar.getInstance();
        lastStartCal.setTime(startDate);
        Calendar targetCal = Calendar.getInstance();
        targetCal.setTime(selectDate);
        int targetYear = targetCal.get(Calendar.YEAR);
        int targetMonth = targetCal.get(Calendar.MONTH);
        // 逐步推算每个周期的生理期，判断是否在目标月份内
        while (true) {
            Calendar currentCal = Calendar.getInstance();
            currentCal.setTime(lastStartCal.getTime());
            // 记录该周期的生理期日期
            for (int i = 0; i < menstrualPeriodDays; i++) {
                Calendar dayCal = Calendar.getInstance();
                dayCal.setTime(lastStartCal.getTime());
                dayCal.add(Calendar.DAY_OF_MONTH, i);
                int year = dayCal.get(Calendar.YEAR);
                int month = dayCal.get(Calendar.MONTH);
                if (year == targetYear && month == targetMonth) {
                    dates.add(dayCal.getTime());
                }
            }
            // 推算下一个周期的开始日期
            lastStartCal.add(Calendar.DAY_OF_MONTH, Convert.toInt(periodDays));
            // 判断是否超过目标月份范围，这里简化判断，可根据实际情况优化
            if (lastStartCal.get(Calendar.YEAR) > targetYear || (lastStartCal.get(Calendar.YEAR) == targetYear && lastStartCal.get(Calendar.MONTH) > targetMonth)) {
                break;
            }
        }
        return dates;
    }

    /**
     * 计算指定月份内的所有生理周期日期
     * @param startDate 起始生理周期日期
     * @param cycleLength 生理周期时长（天数）
     * @param targetYear 目标年份
     * @param targetMonth 目标月份（1-12）
     * @return 该月份内的所有生理周期日期列表
     */
    public static List<Date> getCyclesInMonth(Date startDate, int cycleLength, int targetYear, int targetMonth) {
        // 参数验证
        if (cycleLength < 1) {
            throw new IllegalArgumentException("生理周期时长必须大于0");
        }
        if (targetMonth < 1 || targetMonth > 12) {
            throw new IllegalArgumentException("月份必须在1-12之间");
        }
        // 转换为LocalDate便于计算
        LocalDate startLocal = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        // 计算目标月份的第一天和最后一天
        LocalDate firstDayOfMonth = LocalDate.of(targetYear, targetMonth, 1);
        LocalDate lastDayOfMonth = firstDayOfMonth.with(TemporalAdjusters.lastDayOfMonth());
        // 计算从起始日期到目标月份第一天的天数差
        long daysToFirstDay = java.time.temporal.ChronoUnit.DAYS.between(startLocal, firstDayOfMonth);

        // 计算目标月份内的第一个可能的周期日期
        long baseN;
        if (daysToFirstDay <= 0) {
            baseN = 0; // 如果起始日期在目标月份或之后
        } else {
            // 计算需要多少个周期才能到达或超过目标月份第一天
            baseN = (daysToFirstDay + cycleLength - 1) / cycleLength;
        }
        // 收集目标月份内的所有周期日期
        List<LocalDate> cycleDatesInMonth = new ArrayList<>();
        while (true) {
            LocalDate cycleDate = startLocal.plusDays(baseN * cycleLength);
            // 检查是否在目标月份内
            if (cycleDate.isAfter(lastDayOfMonth)) {
                break;
            }
            cycleDatesInMonth.add(cycleDate);
            baseN++;
        }
        // 转换回Date类型
        List<Date> result = new ArrayList<>();
        for (LocalDate localDate : cycleDatesInMonth) {
            result.add(Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
        }
        return result;
    }

    /**
     * 计算排卵期日期
     * @param menstrualDates 生理期日期列表
     * @param periodDays 周期间隔天数
     * @return 排卵期日期列表
     */
    private static List<Date> calculateOvulationDates(List<Date> menstrualDates, long periodDays) {
        List<Date> ovulationDates = new ArrayList<>();
        if (menstrualDates.isEmpty()) {
            return ovulationDates;
        }
        // 简化逻辑：排卵期在下次生理期前14天左右，这里取生理期结束后第5 - 10天左右（可根据专业生理知识调整）
        Calendar ovulationCal = Calendar.getInstance();
        ovulationCal.setTime(menstrualDates.get(menstrualDates.size() - 1));
        ovulationCal.add(Calendar.DAY_OF_MONTH, 5);
        for (int i = 0; i < 6; i++) {
            Calendar dayCal = Calendar.getInstance();
            dayCal.setTime(ovulationCal.getTime());
            dayCal.add(Calendar.DAY_OF_MONTH, i);
            ovulationDates.add(dayCal.getTime());
        }
        return ovulationDates;
    }

    /**
     * 将日期列表格式化为用逗号分隔的字符串
     * @param dates 日期列表
     * @return 格式化后的字符串
     */
    private static String formatDateList(List<Date> dates) {
        StringBuilder sb = new StringBuilder();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < dates.size(); i++) {
            sb.append(sdf.format(dates.get(i)));
            if (i < dates.size() - 1) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    /**
     * 月经期开始日
     * @param startDate 月经期开始日
     * @param cycleDays 月经周期天数
     */
    public static Date predictNextPeriodStart(Date startDate, int cycleDays) {
        return DateUtils.addDays(startDate, cycleDays);
    }

    /**
     * 月经期结束日
     * @param startDate 月经期开始日
     * @param periodDays 经期持续天数
     */
    public static Date predictNextPeriodEnd(Date startDate, int periodDays) {
        // 例如：1号开始，持续5天，结束日是 1 + 5 - 1 = 5号
        return DateUtils.addDays(startDate, periodDays - 1);
    }

    /**
     * 预测排卵日
     * 医学上通常认为排卵日发生在下次月经来潮前的14天左右。
     * @param startDate 月经期开始日
     */
    public static Date predictOvulationDay(Date startDate) {
        return DateUtils.addDays(startDate, 14);
    }

    /**
     * 预测易孕期/排卵期
     * 通常是指排卵日的前5天和后2天，共7天。
     * @param ovulationDay 预测的排卵日
     * @return 包含易孕期开始和结束日期的 FertilePeriod 对象
     */
    public static Date predictFertileStart(Date ovulationDay) {
        return DateUtils.addDays(ovulationDay, -5);
    }
    /**
     * 预测易孕期/排卵期
     * 通常是指排卵日的前5天和后2天，共7天。
     * @param ovulationDay 预测的排卵日
     * @return 包含易孕期开始和结束日期的 FertilePeriod 对象
     */
    public static Date predictFertileEnd(Date ovulationDay) {
        return DateUtils.addDays(ovulationDay, 2);
    }


    public static void main(String[] args) {
        // --- 准备数据 ---
        // 注意：Calendar 的月份是从 0 开始的 (0代表1月, 11代表12月)
        Calendar cal = Calendar.getInstance();
        cal.set(2025, Calendar.SEPTEMBER, 8); // 上次生理期开始日：2025年9月1日
        Date date = cal.getTime();
        Date lastPeriodStart = DateUtils.queryMonthOfYear(date,28);
//        log.info("初始: " + DateUtils.dateTime(lastPeriodStart));
        int menstrualPeriodDays = 6; // 经期持续5天
        int periodDays = 28; // 周期28天
        // --- 执行计算 ---
        Date periodStartDate = predictNextPeriodStart(lastPeriodStart, periodDays);
        Date periodEndDate = predictNextPeriodEnd(periodStartDate, menstrualPeriodDays);
        Date ovulationDayDate = predictOvulationDay(periodStartDate);
        Date predictFertileStart = predictFertileStart(ovulationDayDate);
        Date predictFertileEnd = predictFertileEnd(ovulationDayDate);
        Date nextPeriodStartDate = predictNextPeriodStart(periodStartDate, periodDays);
        Date nextPeriodEndDate = predictNextPeriodEnd(nextPeriodStartDate, menstrualPeriodDays);
        // --- 输出结果 ---
        log.info("月经期开始日: " + DateUtils.dateTime(periodStartDate));
        log.info("月经期结束日: " + DateUtils.dateTime(periodEndDate));
        log.info("预测排卵日: " + DateUtils.dateTime(ovulationDayDate));
        log.info("预测排期开始: " + DateUtils.dateTime(predictFertileStart));
        log.info("预测排期结束: " + DateUtils.dateTime(predictFertileEnd));
        log.info("下次月经期开始日1: " + DateUtils.dateTime(nextPeriodStartDate));
        log.info("下次月经期结束日1: " + DateUtils.dateTime(nextPeriodEndDate));

        // 生理期（记录日用逗号隔开）
        List<String> mpDays = DateUtils.getDayStringsBetweenDate(periodStartDate,periodEndDate);
        String menstrualPeriod = mpDays.stream().collect(Collectors.joining(","));
        log.info(menstrualPeriod);

        // 排卵日 */
        String ovulationDay = DateUtils.dateTime(ovulationDayDate);
        log.info(ovulationDay);

        // 排卵期（记录日用逗号隔开）
        List<String> opDays = DateUtils.getDayStringsBetweenDate(predictFertileStart,predictFertileEnd);
        String ovulationPeriod = opDays.stream().collect(Collectors.joining(","));
        log.info(ovulationPeriod);

        // 预测生理期（记录日用逗号隔开）
        List<String> days = DateUtils.getDayStringsBetweenDate(nextPeriodStartDate,nextPeriodEndDate);
        String predictMenstrualPeriod = days.stream().collect(Collectors.joining(","));
        log.info(predictMenstrualPeriod);
    }

//    public static void main(String[] args) {
//        long menstrualPeriodDays = 5; // 生理期天数
//        long periodDays = 21; // 周期间隔天数
//        Date startDate = new Date(); // 上次生理期开始日期
//        Date selectDate = DateUtils.queryMonthOfYear(startDate,63);// 选择的时间
//        List<Date> menstrualDates = calculateDatesInMonth(startDate, selectDate, menstrualPeriodDays, periodDays);
//        List<Date> ovulationDates = calculateOvulationDates(menstrualDates, periodDays);
//        log.info("---");
//    }
//    public static void main(String[] args) {
//        // 定义要显示的年份和月份
//        int year = 2026;
//        int month = 1;
//        // 创建 YearMonth 对象，表示 2025 年 9 月
//        YearMonth currentYearMonth = YearMonth.of(year, month);
//        // 获取该月的第一天
//        LocalDate firstDay = currentYearMonth.atDay(1);
//        // 获取该月的最后一天的日期（即该月的总天数）
//        int lastDayOfMonth = currentYearMonth.lengthOfMonth();
//        // 获取该月第一天是星期几
//        DayOfWeek firstDayOfWeek = firstDay.getDayOfWeek();
//
//        // ========== 新增：处理上个月的日期 ==========
//        // 获取上个月的 YearMonth
//        YearMonth lastYearMonth = (month == 1) ? YearMonth.of(year - 1, 12) : YearMonth.of(year, month - 1);
//        // 获取上个月的最后一天
//        LocalDate lastDayOfLastMonth = lastYearMonth.atEndOfMonth();
//        int lastDayValueOfLastMonth = lastDayOfLastMonth.getDayOfMonth();
//        // 计算需要打印的上个月日期数量
//        int lastMonthDaysToPrint = firstDayOfWeek.getValue();
//
//        // 打印星期标题，使用中文显示
//        log.info("\n日\t一\t二\t三\t四\t五\t六");
//        // 打印上个月的日期
//        for (int i = lastDayValueOfLastMonth - lastMonthDaysToPrint + 1; i <= lastDayValueOfLastMonth; i++) {
//            System.out.print(i + "\t");
//        }
//        // ========== 新增结束 ==========
//
//
//        // 打印该月的所有日期
//        for (int day = 1; day <= lastDayOfMonth; day++) {
//            // 这里可以根据需要，对特定日期进行特殊标记（比如上图中的颜色标记，在控制台可以用文字或符号模拟）
//            // 简单打印日期
//            System.out.print(day + "\t");
//            // 每行 7 个日期，换行
//            if ((firstDayOfWeek.getValue() + day - 1) % 7 == 6) {
//                log.info();
//            }
//        }
//        // 打印下个月的部分日期（如果有）
//        int nextMonthDaysToPrint = 7 - (firstDayOfWeek.getValue() + lastDayOfMonth - 1) % 7 - 1;
//        for (int i = 1; i <= nextMonthDaysToPrint; i++) {
//            System.out.print(i + "\t");
//        }
//    }

}
